/**
*	OMaster - Cheating Tool OGame
Door: Peter Evers
Datum: 9 Juli 2007 (morgen is mijn mama jarig!)

	Bestand: connect.cpp
	Beschrijving:
	Dit bestand zorgt er voor dat de juiste pagina's worden opgehaald, geparsed en worden
	door gegeven aan COMaster die de juiste acties vervolgens onderneemt.
	
**/

#include "connect.h"

// constructor
CConnect::CConnect() : m_bDataLoaded(false), curl(NULL), m_szReceivedPage(NULL), m_iPageSize(0)
{              
    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init();     
	
    if(curl)
    {
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
		m_bDataLoaded = true;
    }
}

// destructor
CConnect::~CConnect()
{
    if(m_szReceivedPage)
		delete[] m_szReceivedPage;
    if(curl)
        curl_easy_cleanup(curl);
}

/**
* Zorg er voor dat er ingelogt wordt op de OGame server.
*
* @param	username	gebruikersnaam van speler.
* @param	password	wachtwoord van speler.
* @param uni				uni-host waarop gespeeld wordt!
* @return boolean	true als er ingelogt kan worden, anders false.
*/
bool CConnect::PostLoginForm(const char *username, const char *password, const char *uni)
{
	if((uni == NULL) || (username == NULL) || (password == NULL))
	{
#ifdef _DEBUG
		std::cout << "ERROR(StartLoginServer): parameter can't be NULL!" << std::endl;
#endif			
		return false;
	}
	
	char szLoginAdress[1024];
	char szPostFields[1024];
	
	curl_easy_setopt(curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
	
	// Maak login-adres
	sprintf(szLoginAdress, "http://%s/game/reg/login2.php", uni);
    curl_easy_setopt(curl, CURLOPT_URL, szLoginAdress);
	
	// Maak login-gegevens
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	
	sprintf(szPostFields, "universe=%s&login=%s&pass=%s&button.x=1&button.y=5&v=2", uni, username, password);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szPostFields);
	
    curl_easy_perform(curl);		// Post it!
	
#ifdef _DEBUG
	WriteDebugInfo(m_szReceivedPage);
#endif
	
	return true;
}

/**
* Ga naar de pagina <page> toe!
*
* @param		page			geeft aan welke pagina opgehaalt moet worden. (een pagina tegelijk)
* @param		session		sessie waarmee ingelogt is.
* @param		uni				uni waarop de speler speelt.
* @param		planet		planeet-id waarop gebouwd gaat worden!
* @return	boolean		true als het lukt om pagina op te halen, anders false.
*/
bool CConnect::GetPage(uint page, const char *session, const char *uni, const char *planet)
{
	char szLoginAdress[1024], szPostFields[1024];
	
	// Haal menu pagina op
	if(page == MENU_OVERVIEW)
		sprintf(szPostFields, "page=overview&session=%s&lgn=1", session);		// TODO: Language?
	else if(page == MENU_BUILDINGS)
		sprintf(szPostFields, "page=b_building&session=%s", session);		
	else if(page == MENU_RESOURCES)
		sprintf(szPostFields, "page=resources&session=%s", session);		
	
	if(planet != NULL)
	{
		sprintf(szPostFields, "%s&cp=%s", szPostFields, planet);
	}
	
	//curl_easy_setopt(curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
	curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szPostFields);
	
	sprintf(szLoginAdress, "http://%s/game/index.php", uni);
	curl_easy_setopt(curl, CURLOPT_URL, szLoginAdress);
	
	curl_easy_perform(curl);
	
	// TODO: Kijken of pagina wel opgehaald kan worden, sessie, enz.
#ifdef _DEBUG
	WriteDebugInfo(m_szReceivedPage);
#endif
	
	return true;
}

/**
* Voer php-script uit voor het bouwen van gebouwen!
*
* @param		id				gebouw-id wat gebouwd moet worden.
* @param		session		sessie van login.
* @param		uni				uni waarin gespeeld wordt.
* @param		planet		planeet-id waarop gebouwd gaat worden!
* @return	boolean.
*/
bool CConnect::BuildBuilding(const int id, const char *session, const char *uni, const char *planet)
{
	if((uni == NULL) || (session == NULL))
	{
#ifdef _DEBUG
		std::cout << "ERROR(BuildBuilding): parameter can't be NULL!" << std::endl;
#endif			
		return false;
	}
	
	char szAdress[1024];
	char szPostFields[1024];
	
	curl_easy_setopt(curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
	
	// Maak bouw-aders
	sprintf(szAdress, "http://%s/game/index.php", uni);
	curl_easy_setopt(curl, CURLOPT_URL, szAdress);
	
	// Maak bouw-gegevens
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	
	sprintf(szPostFields, "page=b_building&session=%s&modus=add&techid=%i&planet=%s", session, id, planet);	// TODO: PLANEET KIEZEN!!!
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szPostFields);
	
	curl_easy_perform(curl);		// Post it!
	
#ifdef _DEBUG
	WriteDebugInfo(m_szReceivedPage);
#endif
	
	return true;	
}

/**
* Schrijft info naar output_overview.tmp.
*
* @param		info		informatie die naar bestand geschreven moet worden.
*/
void CConnect::WriteDebugInfo(const char *info)
{
	   // DEBUG
    FILE *fp = fopen("Data/output_overview.tmp", "wb");
    if(!fp)
	{
#ifdef _DEBUG
		std::cout << "ERROR(LoadSession): Kan bestand \"Data/output_overview.tmp\" niet aanmaken!" << std::endl;
#endif
        return;
	}
	if(strlen(info) > 0)
		fwrite(info, 1, strlen(info), fp);
    fclose(fp);
}

/**
* Geeft aan of libcurl goed geinitialiseerd is.
*/
bool CConnect::operator!()
{
    return m_bDataLoaded;
}

/**
* Libcurl callback functie.
*/
size_t CConnect::write_data(void *buffer, size_t size, size_t nmemb, CConnect *userp)
{
    if(!userp->m_szReceivedPage)
    {
		userp->m_iPageSize = size * nmemb;
		userp->m_szReceivedPage = new char[userp->m_iPageSize + 1];
		strcpy(userp->m_szReceivedPage, (char*)buffer);
		userp->m_szReceivedPage[size * nmemb] = '\0';
    }
    else
    {
        int iRealSize = size * nmemb;
		char *szTemp = new char[userp->m_iPageSize + 1];	// Buffer temp-data en maak m_szPageReceived groter
		strcpy(szTemp, userp->m_szReceivedPage);
		
		delete[] userp->m_szReceivedPage;
		userp->m_szReceivedPage = new char[iRealSize + userp->m_iPageSize + 1];	// Grootte van nieuwe tekst + oude + NULL-character
		strcpy(userp->m_szReceivedPage, szTemp);
		delete[] szTemp;
		memcpy(&(userp->m_szReceivedPage[userp->m_iPageSize]), (char*)buffer, iRealSize);
		userp->m_iPageSize += iRealSize;	// Nieuwe grootte van geheelte	*/
    }
    return (size * nmemb);
}

/**
* Verwijderd de laatst opgehaalde pagina.
*/
void CConnect::RefreshPage()
{
	delete[] m_szReceivedPage;
	m_szReceivedPage = NULL;
}

/**
* Geeft de laatst opgevraagde pagina terug.
*/
char *CConnect::GetLastPage()
{
    return m_szReceivedPage;
}

